import log from './logger'
import settings from "./settings";
import player from "./player";
import controller from "./controller";
// import plate from "./plate";
import state from "./states/state";
import printer from "./printer";
import {EventEmitter, mqtt} from "../node-test";
import weight from "./weight";
import weighter from "./weight";
import plate from "./plate";

class MqttIot extends EventEmitter {
    sayService(res: any) {
        log.info('mqtt say called,res:' + JSON.stringify(res));
        player.say(res.text);
    }

    openRLService(res: any) {
        log.info('mqtt openRl called,res:' + JSON.stringify(res));
        // controller.onlyOpenRL(res.i);
        controller.openRL(res.i);
    }

    // closeRLService(res: any) {
    // log.info('mqtt closeRl called,res:' + JSON.stringify(res));
    // controller.onlyCloseRL(res.i);
    // }

    printService(res: any) {
        log.info('mqtt print called,res:' + JSON.stringify(res));
        printer.print(res.count, res.data, res.type, res.paper)
    }

    driverRequestService(req: any) {
        log.info('mqtt driverRequest called,res:' + JSON.stringify(req));
        state.driverRequest(req.type);
    }

    enableService(req: any) {
        log.info('mqtt enableService called,res:' + JSON.stringify(req));
        state.enable = req.enable === 1;
    }

    doWeighService(req: any) {
        log.info('mqtt doWeighService called,res:' + JSON.stringify(req));
        // 实际毛重、两次毛重实际差值（实际净重 = 矿发净重 + 毛重实际差值）
        this.emit("do_weigh", {
            "weight": req.weight,
            "deductionWeight": req.deductionWeight,
        });
    }

    ignoreService(req: any) {
        log.info('mqtt ignoreService called,res:' + JSON.stringify(req));
        controller.ignore = req.ignore === 1;
    }

    init() {
        log.info("mqtt server:", settings.mqttServer);
        let client = mqtt.connect('mqtt://' + settings.mqttServer, {
            username: "client1",
            password: "Hlsk@1234",
            protocolVersion: 5,
            clientId: settings.deviceName + "-" + Date.now().toString(16),
            clean: false
        })
        client.on("connect", () => {
            log.info("mqtt connected")
        })
        client.on("error", (error: any) => {
            log.error("mqtt error", error)
        })
        client.on("reconnect", () => {
            log.info("mqtt reconnect")
        })
        client.subscribe(`weigh_node/${settings.deviceName}/service/+`, {qos: 1})

        client.on("message", (topic, payload) => {
            console.log([topic, payload].join(": "))
            const serviceCode = topic.replace(`weigh_node/${settings.deviceName}/service/`, "")
            if ("say" === serviceCode) {
                this.sayService(JSON.parse(payload.toString()))
            }
            if ("openRL" === serviceCode) {
                this.openRLService(JSON.parse(payload.toString()))
            }
            if ("closeRL" === serviceCode) {
                // this.closeRLService(JSON.parse(payload.toString()))
            }
            if ("print" === serviceCode) {
                this.printService(JSON.parse(payload.toString()))
            }
            if ("driverRequest" === serviceCode) {
                this.driverRequestService(JSON.parse(payload.toString()))
            }
            if ("enable" === serviceCode) {
                this.enableService(JSON.parse(payload.toString()))
            }
            // 过磅完成
            if ("doWeigh" === serviceCode) {
                this.doWeighService(JSON.parse(payload.toString()));
            }
            // 忽略红外
            if ("ignore" === serviceCode) {
                this.ignoreService(JSON.parse(payload.toString()));
            }
        })

        // 重量上报
        weight.on('weight_data', (weight: number, wen: boolean) => {
            const msg = {
                weight, wen,
            }
            client.publish(`weigh_node/${settings.deviceName}/event/weight_data`, JSON.stringify(msg), {qos: 0});
        })

        // 状态上报
        state.on('state', (currState: string) => {
            const msg = {
                state: currState,
                manualDoWeigh: state.manualDoWeigh,
                senderName: state.senderName,
                customerName: state.customerName,
                vehicleNumber: state.getVehicleNumber(),
                primaryWeight: state.primaryWeight,
                expectedNetWeight: state.expectedNetWeight,
                weight: weight.weight,
                wen: weight.wen
            }
            client.publish(`weigh_node/${settings.deviceName}/event/state`, JSON.stringify(msg), {
                qos: 0,
                retain: true
            });
        })

        // 控制器状态上报
        controller.on("active", (active: boolean[]) => {
            const msg = {
                active,
            }
            client.publish(`weigh_node/${settings.deviceName}/event/active`, JSON.stringify(msg), {qos: 0});
        })

        // 道闸状态上报
        controller.on("activeD", (activeD: boolean[]) => {
            const msg = {
                activeD,
            }
            client.publish(`weigh_node/${settings.deviceName}/event/activeD`, JSON.stringify(msg), {qos: 0});
        })

        // 定时上报监控数据
        setInterval(() => {
            const msg = {
                r1State: controller.R1,
                r2State: controller.R2,
                comState: weighter.available,
                carNumState: plate.available,
                carNum: state.getVehicleNumber(),
                weight: weighter.weight,
                ignore: settings.ignore,
                normalOpen: settings.normalOpen,
                msg: player.lastMsg
            }
            client.publish(`weigh_node/${settings.deviceName}/event/monitor`, JSON.stringify(msg), {qos: 0});
        }, 1000)
    }
}

const mqttIot = new MqttIot();
export default mqttIot;